package com.dimples.dd.system.model.entity;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
import com.dimples.dd.common.util.json.JsonUtils;
import com.dimples.dd.mybatis.core.dataobject.BaseDO;
import com.dimples.dd.system.framework.file.core.client.FileClientConfig;
import com.dimples.dd.system.framework.file.core.client.db.DBFileClientConfig;
import com.dimples.dd.system.framework.file.core.client.ftp.FtpFileClientConfig;
import com.dimples.dd.system.framework.file.core.client.local.LocalFileClientConfig;
import com.dimples.dd.system.framework.file.core.client.s3.S3FileClientConfig;
import com.dimples.dd.system.framework.file.core.client.sftp.SftpFileClientConfig;
import com.dimples.dd.system.framework.file.core.enums.FileStorageEnum;
import com.fasterxml.jackson.core.type.TypeReference;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;

/**
 * 文件配置表
 */
@Schema(description = "文件配置表")
@Data
@EqualsAndHashCode(callSuper = true)
@TableName(value = "system_file_config", autoResultMap = true)
public class SystemFileConfigDO extends BaseDO {
    /**
     * 编号
     */
    @TableId(value = "id", type = IdType.AUTO)
    @Schema(description = "编号")
    private Long id;

    /**
     * 配置名
     */
    @TableField(value = "`name`")
    @Schema(description = "配置名")
    private String name;

    /**
     * 存储器
     * {@link FileStorageEnum}
     */
    @TableField(value = "`storage`")
    @Schema(description = "存储器")
    private String storage;

    /**
     * 备注
     */
    @TableField(value = "remark")
    @Schema(description = "备注")
    private String remark;

    /**
     * 是否为主配置
     */
    @TableField(value = "master")
    @Schema(description = "是否为主配置")
    private Boolean master;

    /**
     * 存储配置
     */
    @TableField(value = "config", typeHandler = FileClientConfigTypeHandler.class)
    @Schema(description = "存储配置")
    private FileClientConfig config;

    public static class FileClientConfigTypeHandler extends AbstractJsonTypeHandler<Object> {

        @Override
        protected Object parse(String json) {
            FileClientConfig config = JsonUtils.parseObjectQuietly(json, new TypeReference<>() {
            });
            if (config != null) {
                return config;
            }

            // 兼容老版本的包路径
            String className = JsonUtils.parseObject(json, "@class", String.class);
            className = StrUtil.subAfter(className, ".", true);
            return switch (className) {
                case "DBFileClientConfig" -> JsonUtils.parseObject2(json, DBFileClientConfig.class);
                case "FtpFileClientConfig" -> JsonUtils.parseObject2(json, FtpFileClientConfig.class);
                case "LocalFileClientConfig" -> JsonUtils.parseObject2(json, LocalFileClientConfig.class);
                case "SftpFileClientConfig" -> JsonUtils.parseObject2(json, SftpFileClientConfig.class);
                case "S3FileClientConfig" -> JsonUtils.parseObject2(json, S3FileClientConfig.class);
                default -> throw new IllegalArgumentException("未知的 FileClientConfig 类型：" + json);
            };
        }

        @Override
        protected String toJson(Object obj) {
            return JsonUtils.toJsonString(obj);
        }

    }
}